(function($){
	var pagePos = 0, epidDbPools = {};

	var Logs = {
		pageSize : 100,
		uploadEntities : [],
		filterEntities : [],

		init : function() {
			// 打开日志
			const a = this;
			$('.page-nav>li').on('click', function(e) {
				e = $(e.currentTarget);
				if (e.hasClass('next-selected'))
					return;
				$('.page-nav>li').removeClass('next-selected');
				e.addClass('next-selected');
				$('.wind-page').hide();
				$('#' + e.attr('data-ref')).show();
				a[e.attr('data-method')]();
			})
			a.initLogsSearch();
			a.initLogsFilter();
			a.initLogsUpload();
			$('.page-nav>li:eq(0)').trigger('click');
		},

		initLogsSearch : function() {
			var a = this,
				panel = $('#logsSearch'),
				srhInput = $(".highlight_box .search>input", panel),
				epidInput = $("input[name=epid]", panel),
				logTime = $('input[name=logTime]', panel);

			// 账号搜索
			srhInput.on('keypress', function(e) {
				if (e.keyCode == 13)
					$("button.js_filter", panel).click();
			})

			// 日志时间搜索
			$('.js_logTime', panel).click(function(e) {
				e.preventDefault();
				logTime.datetimepicker({
					zIndex : 100002,
					fixed : true,
					showOnFocus : false,
					//mask : 'Y-m-d',
					format : 'Y-m-d',
					datepicker : true,
					timepicker : false
				})
			})

			var epid = $E.admin.epid.toUpperCase(), dbPool = '';
			$("button.js_filter", panel).off('click').on('click', function() {
				var search = '%' + srhInput.val().toLowerCase() + '%', time = logTime.val(), start, end;
				if (! time) {
					time = new Date();
					start = time.format('yyyy-MM-dd 00:00:00');
					end = time.format('yyyy-MM-dd 23:59:59.999');
				} else {
					time = $F.parseDate(time);
					start = time.format('yyyy-MM-dd') + ' 00:00:00';
					end = time.format('yyyy-MM-dd') + ' 23:59:59.999';
				}

				if ($E.dataService.saas && epid === '') {
					// 主库管理员登录模式，可以设定epid值
					epid = epidInput.val().toUpperCase();
					if (epid) {
						// 如果需要读取epid库的登录信息，则需要获取epid的对应dbpool
						dbPool = epidDbPools[epid];
						if (! dbPool) {
							$F.dataService('SystemDo2', {
								data: $F.sqlbean('System.saas.dbpool', $E.admin.token, [epid]),
								async: false,
								digest: $E.admin.ordIndex,
								success: function(data) {
									if (data.code > 0) {
										if (data.value[0].count > 0) {
											dbPool = data.value[0].fields[0][0];
											epidDbPools[epid] = dbPool;
										} else
											$F.notify('EPID不存在配置记录:' + epid, -1);
									} else
										$F.notify(data.message, -1)
								}
							})
						}
					}
				}

				// 读入所有查询的token
				tokensTable.setData([]);
				$F.dataService('SystemDo2', {
					data: {
						token: $E.admin.token,
						dbPool: dbPool,
						sqls: [{
							key: 'System.Login.His',
							params: {
								C1: start,
								C2: end,
								C3: search,
								C4: (epid? ('_' + epid) : '')
							},
							maxRow: 50
						}]
					},
					digest: $E.admin.ordIndex,
					successResult: function(data) {
						console.log(data)
						tokensTable.setData($F.makeJsonArray(data[0]));
						tokensTable.timeRange = time;
					}
				});
			})
			$('.js_all_log', panel).off('click').on('click', function(e) {
				a.onJsServiceSearch(epid, '*', {
					STAFFNAME: '全部',
					LOGINUUID: ''
				});
			})

			// select keyid,loginGroup,LoginID,StaffID,StaffName,Computer,LoginDate,LastModifyDate,LogoutDate,LogoutType
			var tokensTable = $(".tokens_list", panel).wisTable({
				border: 0,
				cookie: 'logs_tokens_wistable',
				dynamicShow: true,
				hideColumnMenu: true,
				resizable: true,
				columns: [
					{
						display: '登录账号',
						name: 'LoginID',
						width: 100,
						resizable: true
					},
					{
						display: '用户名称',
						name: 'StaffName',
						width: 120,
						resizable: true
					},
					{
						display: '组',
						name: 'loginGroup',
						width: 100,
						resizable: true
					},
					{
						display: '登录类型',
						name: 'CLIENTFLAG',
						width: 100,
						resizable: true
					},
					{
						display: '登录时间',
						name: 'LoginDate',
						width: 180,
						resizable: true
					},
					{
						display: '登出时间',
						name: 'LogoutDate',
						width: 180,
						resizable: true
					},
					{
						display: '登出类型',
						name: 'LogoutType',
						width: 100,
						resizable: true
					},
					{
						display: 'TOKEN',
						name: 'TOKEN',
						width: 300,
						resizable: true
					},
					{
						display: '客户端IP',
						name: 'Computer',
						width: 150,
						resizable: true
					}
				],
				models: function(data, row, col) {
					// DATA COLUMNS
					// 0: "KEYID"
					// 1: "LOGINGROUP"
					// 2: "LOGINID"
					// 3: "STAFFID"
					// 4: "STAFFNAME"
					// 5: "COMPUTER"
					// 6: "LOGINDATE"
					// 7: "LASTMODIFYDATE"
					// 8: "LOGOUTDATE"
					// 9: "LOGOUTTYPE"
					// 10: "CLIENTFLAG"
					switch(col) {
						case 0:
							return data.LOGINID;
						case 1:
							return data.STAFFNAME;
						case 2:
							return data.LOGINGROUP;
						case 3:
							switch(data.CLIENTFLAG) {
								case 0:
									return 'Utility';
								case 1:
									return '坐席';
								case 2:
									return '移动';
								case 3:
									return '工单';
								case 4:
									return '管理台';
								case 5:
									return '软电话';
								case 7:
									return 'CRM';
								default:
									return data.CLIENTFLAG;
							};
						case 4:
							return data.LOGINDATE;
						case 5:
							return data.LOGOUTDATE;
						case 6:
							switch(data.LOGOUTTYPE) {
								case 0:
									return '';
								case 1:
									return '正常登出';
								case -1:
								case -20:
								case -10:
									return '强杀';
								case 100:
									return '异常退出';
								default:
									return data.LOGOUTTYPE;
							};
						case 7:
							return data.KEYID;
						case 8:
							return data.CLIENTIP;
						default:
							return '';
					}
				},
				onDblClick: function(data, row) {
					a.onJsServiceSearch(epid, tokensTable.timeRange, data);
				}
			})
		},

		onLogsSearch() {
			var a = this;
			$('.wind-page').hide();
			$('#logsSearch').show();
		},

		onJsServiceSearch : function(epid, time, tokenBean) {
			var a = this,
				panel = $('#logsSearch').show(),
				tokensPanel = $('.tokens_content', panel).hide(),
				logsContent = $('.logs_content', panel).css('display', 'flex');
			$(".info_staff>span", logsContent).text(tokenBean.STAFFNAME);
			$(".info_token>span", logsContent).text(tokenBean.LOGINUUID);
			$(".info_epid>span", logsContent).text(epid);

			$('.logpage', logsContent).hide();
			$('.logTableBox', logsContent).hide();
			var searcher = $('.searchPanel', logsContent).show();
			var searchKey = $('input[name=searchKey]', searcher).val('');
			var logType = $('select[name=logtype]', searcher).val('');
			var tag = $('select[name=tag]', searcher).val('');
			$('.js_refreshLogs', searcher).off('click').on('click', function(e) {
				a.loadJsServiceLogs(epid, tokenBean.LOGINUUID, time, logType.val(), tag.val(), searchKey.val());
			})
			$('.js_back', searcher).off('click').on('click', function(e) {
				logsContent.hide();
				tokensPanel.show();
			})
		},

		loadJsServiceLogs : function(epid, token, time, logType, tag, filter) {
			let timeFormatRegex = $E.logIndex.match(/%d{(.*)}/),
				timeRange = time instanceof Date ? time.format('yyyy-MM-dd') : time;
			if (timeFormatRegex && timeFormatRegex[1] && time instanceof Date)
				timeRange = time.format(timeFormatRegex[1] || 'yyyy-MM-dd');
			var a = this,
				options = {
					indexAuto: !!(timeFormatRegex && timeFormatRegex[1]),
					epid : epid,
					token : token,
					timeRange: timeRange,
					logtype: logType,
					tag: tag,
					filter : filter,
					pageSize: a.pageSize
				},
				pagePos = 0;
			if ($E.logService == 'mongodb') {
				Ajax.post({
					url : $E.url + '/admin/logQuery_',
					data : options,
					success : function(data) {
						if (data.code > 0)
							a.displayJsServiceLogs(data.value, options);
						else
							$F.alert(data.message)
					},
					always : function() {
						$F.busyHide(busyId);
					}
				})
			} else if ($E.logService == 'es')
				a._loadJsServiceLogs(options);
		},

		_loadJsServiceLogs: function(options, prev) {
			let a = this,
				busyId = $F.busyShow(),
				index = $E.logIndex.replaceAll(/%d{(.*)}/, options.indexAuto ? options.timeRange : '');
			const query = {
				"bool": {
					"must": [],
					"filter": []
				}
			};
			if (options.filter) {
				query.bool.must.push({
					'match': {
						'message': options.filter
					}
				})
			}
			if (!options.indexAuto) {
				query.bool.filter.push({
					'match': {
						'@timestamp': options.timeRange
					}
				})
			}
			if (options.token) {
				query.bool.filter.push({
					'match': {
						'token': {
							'query': options.token,
							'operator': 'and'
						}
					}
				})
			}
			if (options.epid) {
				query.bool.filter.push({
					'match': {
						'epid': {
							'query': options.epid,
							'operator': 'and'
						}
					}
				})
			}
			if (options.tag) {
				if (options.tag == 'sql') {
					query.bool.filter.push({
						"exists": {
							"field": "tag"
						}
					})
				} else {
					query.bool.filter.push({
						'match': {
							'tag': {
								'query': options.tag,
								'operator': 'and'
							}
						}
					})
				}
			}
			if (options.logtype) {
				query.bool.filter.push({
					'match': {
						'severity': {
							'query': options.logtype,
							'operator': 'and'
						}
					}
				})
			}

			let range, sort = "desc";
			if (options.timestamp) {
				if (prev) {
					// goto previous page
					range = {
						'@timestamp' : {
							'lt' : options.timestamp
						}
					}
				} else {
					// goto next page
					range = {
						'@timestamp' : {
							'gt' : options.timestamp
						}
					}
					sort = "asc"
				}
			}
			if (options.timestamp) {
				query.bool.filter.push({
					'range': range
				});
			}

			const content = {
				"query": query,
				"sort": {
					"@timestamp": sort
				},
				size: options.pageSize
			};
			//console.log(content);
			elasticsearch.search(content, function(results) {
				$F.busyHide(busyId)
				//console.log(results);
				a.displayJsServiceLogs2((sort == 'desc' ? results.hits.hits.reverse() : results.hits.hits), options);
			}, function(error) {
				$F.busyHide(busyId)
				console.error(index + ': ', error);
			}, index, 'jss');
		},

		displayJsServiceLogs2 : function(logs, options) {
			var a = this, panel = $('#logsSearch'), logPanel = $('.logPanel', panel);
			$('.searchPanel', logPanel).hide();
			$('.logTableBox', logPanel).show();
			var opr = $('.logpage', panel).show();
			$('.js_prevPage', opr).off('click').on('click', function() {
				options.timestamp = logs[0]._source['@timestamp'];
				pagePos ++;
				a._loadJsServiceLogs(options, 1)
			}).prop('disabled', (logs.length < options.pageSize));
			$('.js_nextPage', opr).off('click').on('click', function() {
				options.timestamp = logs[logs.length-1]._source['@timestamp'];
				pagePos --;
				a._loadJsServiceLogs(options, 0)
			}).prop('disabled', (pagePos == 0 || logs.length == 0));
			$('.js_back', opr).off('click').on('click', function() {
				$('.logTableBox', logPanel).hide();
				$('.searchPanel', logPanel).show();
				opr.hide();
			});
			$('.js_back2', opr).off('click').on('click', function() {
				$('.logTableBox', logPanel).hide();
				$('.searchPanel', logPanel).show();
				opr.hide();
				$('#logsSearch .logs_content').hide();
				$('#logsSearch .tokens_content').show();
			})

			var logTable = $('.logTable', logPanel).empty();
			$.each(logs, function(i, v){
				var log = v._source;
				var	tdMessage = $('<td class="item_message"></td>').data('message', log.message),
					tr = $('<tr class="' + log.severity + '">')
						.append('<td class="line">' + (i + 1) + '</td>')
						.append('<td class="item_timestamp">' + new Date(log['@timestamp']).format('yyyy-MM-dd HH:mm:ss.S') + '</td>')
						.append('<td class="item_level severity">' + log.severity + '</td>')
						.appendTo(logTable),
					tdTag = $('<td class="item_tag">[' + (log.tag || '').toUpperCase() + ']</td>');
				if (! options.token) {
					tr.append('<td class="item_level">[' + (log.epid || '') + ']</td>');
					tr.append('<td class="item_level"><span class="token">[' + (log.token || '') + ']</span></td>')
				} else {
					if (log.token !== options.token)
						$('td.item_timestamp', tr).css('color', 'red');
				}
				tr.append(tdTag);
				tr.append(tdMessage);
				if (log.level == 'ERROR') {
					var j = $('<a class="" href="javascript:;">' + log.message + '</a>').on('click', function(e) {
						e.preventDefault();
						if (! log.thrown) {
							var detail = '<ul><li>' + log.message + '</li>';
							detail += '<li class="detail">at  ' + log.source.className + '.' + log.source.methodName + '(';
							detail += log.source.fileName + ':' + log.source.lineNumber;
							detail += ')</ul>';
						} else {
							var detail = '<ul><li>' + log.thrown.type + ': ' + log.thrown.message + '</li>';
							$.each(log.thrown.stackTrace, function(i, stack) {
								detail += '<li class="detail">at  ' + stack.className + '.' + stack.methodName + '(';
								if (stack.fileName == null)
									detail += 'Unknown';
								else
									detail += stack.fileName + ':' + stack.lineNumber;
								detail += ')';
							})
							detail += '</ul>';
						}
						var jt = $('.js_thrown').html(detail);
						Helper.masker.show(jt, {
							clickToHide : true
						});
					});
					tdMessage.append(j);
				} else {
					tdMessage.html('<span>' + log.message + '</span>');
				}
				// 选中风格
				tdMessage.on('click', function(e) {
					$('.item_message').removeClass('selected');
					$(e.currentTarget).addClass('selected');
				})
				// 双击进行翻译
				tdMessage.on('dblclick', function(e) {
					var msg = $(e.currentTarget).data('message'), jt = $('.js_transsql'), sql = replaceSql(msg);
					$('>.log', jt).html('<span>' + sql + '</span>');
					var copy = $('>a', jt).off('click').on('click', function(e) {
						e.preventDefault();
						H5Utils.clip(Helper.htmlDecode(sql), function(){
							$F.notify('已经复制到剪贴板', 1);
						})
					})
					jt.off('scroll').on('scroll', function(e) {
						copy.stop().animate({
							top: (jt.scrollTop() + 10) + 'px'
						})
					})
					Helper.masker.show(jt, {
						clickToHide : true,
						fixed: false
					});
				})

				if (log.tag && log.tag.startWith('sql')) {
					// 需要翻译SQL
					var trans = $('<a class="translater" href="javascript:;">' + log.tag + '</a>')
						.on('click', function(e) {
							tdMessage.trigger('dblclick');
						})
					tdTag.empty().append(trans);
				}
			})

			logPanel.scrollTop(logPanel[0].scrollHeight);
		},

		displayJsServiceLogs : function(logs, options) {
			var a = this, categoryPanel = $('#logsSearch'), logPanel = $('.logPanel', categoryPanel);
			$('.searchPanel', logPanel).hide();
			$('.logTableBox', logPanel).show();
			var opr = $('.logpage', categoryPanel).show();
			$('.js_prevPage', opr).off('click').on('click', function() {
				var busyId = $F.busyShow('正在抽取上一页');
				options.timestamp = logs[0].date;
				Ajax.post({
					url : $E.url + '/admin/logQueryPrevPage_',
					data : options,
					success : function(data) {
						if (data.code > 0) {
							pagePos ++;
							a.displayJsServiceLogs(data.value, options);
						} else
							$F.alert(data.message);
					},
					always : function() {
						$F.busyHide(busyId);
					}
				})
			}).prop('disabled', (logs.length < a.pageSize));
			$('.js_nextPage', opr).off('click').on('click', function() {
				var busyId = $F.busyShow('正在抽取下一页');
				options.timestamp = logs[logs.length - 1].date;
				Ajax.post({
					url : $E.url + '/admin/logQueryNextPage_',
					data : options,
					success : function(data) {
						if (data.code > 0) {
							pagePos --;
							a.displayJsServiceLogs(data.value, options);
						} else
							$F.alert(data.message);
					},
					always : function() {
						$F.busyHide(busyId);
					}
				})
			}).prop('disabled', (pagePos == 0));
			$('.js_back', opr).off('click').on('click', function() {
				$('.logTableBox', logPanel).hide();
				$('.searchPanel', logPanel).show();
				opr.hide();
			})

			var logTable = $('.logTable', logPanel).empty();
			$.each(logs, function(i, log){
				var	tdMessage = $('<td class="item_message"></td>').data('message', log.message),
					tr = $('<tr class="' + log.level + '">')
						.append('<td class="line">' + (i + 1) + '</td>')
						.append('<td class="item_timestamp">' + log.date + '</td>')
						.append('<td class="item_level">' + log.level + '</td>')
						.appendTo(logTable),
					tdTag = $('<td class="item_tag">[' + (log.contextMap.tag || '').toUpperCase() + ']</td>');
				if (! options.token) {
					tr.append('<td class="item_level">[' + (log.contextMap.epid || '') + ']</td>');
					tr.append('<td class="item_level">[' + (log.contextMap.token || '') + ']</td>')
				}
				tr.append(tdTag);
				tr.append(tdMessage);
				if (log.level == 'ERROR') {
					var j = $('<a class="" href="javascript:;">' + log.message + '</a>').on('click', function(e) {
						e.preventDefault();
						if (! log.thrown) {
							var detail = '<ul><li>' + log.message + '</li>';
							detail += '<li class="detail">at  ' + log.source.className + '.' + log.source.methodName + '(';
							detail += log.source.fileName + ':' + log.source.lineNumber;
							detail += ')</ul>';
						} else {
							var detail = '<ul><li>' + log.thrown.type + ': ' + log.thrown.message + '</li>';
							$.each(log.thrown.stackTrace, function(i, stack) {
								detail += '<li class="detail">at  ' + stack.className + '.' + stack.methodName + '(';
								if (stack.fileName == null)
									detail += 'Unknown';
								else
									detail += stack.fileName + ':' + stack.lineNumber;
								detail += ')';
							})
							detail += '</ul>';
						}
						var jt = $('.js_thrown').html(detail);
						Helper.masker.show(jt, {
							clickToHide : true
						});
					});
					tdMessage.append(j);
				} else {
					tdMessage.html('<span>' + log.message + '</span>');
				}
				// 选中风格
				tdMessage.on('click', function(e) {
					$('.item_message').removeClass('selected');
					$(e.currentTarget).addClass('selected');
				})
				// 双击进行翻译
				tdMessage.on('dblclick', function(e) {
					var msg = $(e.currentTarget).data('message'), jt = $('.js_transsql'), sql = replaceSql(msg);
					$('>.log', jt).html('<span>' + sql + '</span>');
					var copy = $('>a', jt).off('click').on('click', function(e) {
						e.preventDefault();
						H5Utils.clip(Helper.htmlDecode(sql), function(){
							$F.notify('已经复制到剪贴板', 1);
						})
					})
					jt.off('scroll').on('scroll', function(e) {
						copy.stop().animate({
							top: (jt.scrollTop() + 10) + 'px'
						})
					})
					Helper.masker.show(jt, {
						clickToHide : true,
						fixed: false
					});
				})

				if (log.contextMap.tag && log.contextMap.tag.startWith('sql')) {
					// 需要翻译SQL
					var trans = $('<a class="translater" href="javascript:;">' + log.contextMap.tag + '</a>')
						.on('click', function(e) {
							tdMessage.trigger('dblclick');
						})
					tdTag.empty().append(trans);
				}
			})

			logPanel.scrollTop(logPanel[0].scrollHeight);
		},

		initLogsFilter: function() {
			var a = this, panel = $('#logsFilter');
			a.loggerConfig(0);
			$('.js_add', panel).off('click').on('click', function(e) {
				a.addConfig(0);
			})
			$('.js_save', panel).off('click').on('click', function(e) {
				a.saveConfig(0);
			})
			$('.js_refresh', panel).off('click').on('click', function(e) {
				var ids = [];
				$.each(a.filterEntities, function(i, v) {
					ids.push(v.STAFF_ID);
				})
				$F.ngsService({
					url: $E.url + '/admin/logFilterUpdate_',
					data: ids,
					success: function(data) {
						if (data.code > 0)
							$F.notify('成功提交日志白名单刷新');
						else
							$F.notify(data.message, -1);
					}
				}, $E.admin.token, $E.admin.ordIndex)
			})
		},

		onLogsFilter : function() {
			var a = this;
			$('.wind-page').hide();
			$('#logsFilter').show();
		},

		initLogsUpload : function() {
			var a = this, panel = $('#logsUpload');
			a.loggerConfig(1);
			$('.js_add', panel).off('click').on('click', function() {
				a.addConfig(1);
			})
			$('.js_save', panel).off('click').on('click', function(e) {
				a.saveConfig(1);
			})
		},

		onLogsUpload : function() {
			const a = this;
			$('.wind-page').hide();
			$('#logsUpload').show();
		},

		/**
		 * 读入已有的名单配置
		 */
		loggerConfig : function(type) {
			const a = this, entities = type ? a.uploadEntities : a.filterEntities, sqlkey = 'Admin.clientlogger.query';
			$F.dataService('SystemDo2', {
				data: $F.sqlbean(sqlkey, $E.admin.token, [type?1:0]),
				digest: $E.admin.ordIndex,
				success: function(data) {
					if (data.code > 0) {
						if (type)
							a.uploadEntities = $F.makeJsonArray(data.value[0]);
						else
							a.filterEntities = $F.makeJsonArray(data.value[0]);
						a.showClientLoggerConfig(type);
					} else
						$F.alert(data.message);
				}
			})
		},

		/**
		 * 显示已有的名单配置
		 */
		showClientLoggerConfig : function(type) {
			var a = this,
				panel = (type ? '#logsUpload' : '#logsFilter'),
				list = $(panel + " .staff_list.body").empty(),
				entities = (type ? a.uploadEntities : a.filterEntities),
				html = '';

			$.each(entities, function(i, v) {

				html += '<li class="item"><span class="flag"><i class="js_flag fal fa-user" data-ref="' + v.STAFF_ID + '"></i></span><span class="staffId">' + v.STAFF_ID + '</span><span class="staffName">' + v.STAFFNAME + '</span><a href="javascript:;" class="js_remove fa fa-fw fa-trash-alt" data-ref="' + v.STAFF_ID + '" style="color: red;"></a></li>'
			});
			list.append(html);
			$('.js_remove', list).on('click', function(e) {
				a.removeClientLoggerConfig(type, $(e.currentTarget));
			})
		},

		removeClientLoggerConfig : function(type, e) {
			var a = this,
				staffId = e.attr('data-ref'),
				li = e.closest('li'),
				entities = (type ? a.uploadEntities : a.filterEntities);

			$F.confirm('确信删除账号[' + staffId + ']吗？', function() {
				if (entities.remove(function(element) {
					if (element.STAFF_ID === staffId)
						return element;
				})) {
					li.remove();
				} else {
					$F.notify('删除账号对象异常', -1)
				}
			})
		},

		addConfig : function(type) {
			var a = this, entities = (type ? a.uploadEntities : a.filterEntities);

			H5Utils.staffSelector({
				token: $E.admin.token,
				digest: $E.admin.ordIndex,
				multi: true,
				callback: function(data) {
					$.each(data, function(i, v) {
						var exist = entities.find(function(element) {
							if (element.STAFF_ID == v.id)
								return element;
						})
						if (exist === undefined) {
							entities.push({
								STAFF_ID : v.id,
								STAFFNAME: v.name
							})
							var panel = (type ? '#logsUpload' : '#logsFilter'), list = $(panel + " .staff_list.body");

							var li = $('<li class="item"><span class="flag"><i class="js_flag fal fa-user" data-ref="' + v.id + '"></i></span><span class="staffId">' + v.id + '</span><span class="staffName">' + v.name + '</span><a href="javascript:;" class="js_remove fa fa-fw fa-trash-alt" data-ref="' + v.id + '" style="color: red;"></a></li>');
							li.appendTo(list);
							$('.js_remove', li).on('click', function(e) {
								a.removeClientLoggerConfig(type, $(e.currentTarget));
							})
						}
					})
				}
			})
		},

		saveConfig : function(type) {
			var a = this, entities = (type ? a.uploadEntities : a.filterEntities);
			var requestData = {
				token: $E.admin.token,
				dbPool: '',
				sqls: [{
					key: 'Admin.clientlogger.clean',
					params: {
						C1: type
					}
				}]
			}
			$.each(entities, function(i, entry) {
				requestData.sqls.push({
					key: 'Admin.clientlogger.insert',
					params: {
						C1: entry.STAFF_ID,
						C2: type
					}
				})
			})
			$F.dataService('SystemDo1', {
				data: requestData,
				digest: $E.admin.ordIndex,
				success: function(data) {
					if (data.code > 0)
						$F.notify('成功保存名单');
					else
						$F.err(data.message)
				}
			})
		}
	};

	var replaceSql = function(str) {
			var sql, i = str.indexOf('Begin Select Sql:');
			if (i == -1) {
				i = str.indexOf('LastSql:');
				if (i == -1) {
					i = str.indexOf('LastBoundSql:');
					if (i == -1) {
						i = str.indexOf('Begin Exec Sql:');
						if (i == -1) {
							i = str.indexOf(' Sql:');
							if (i == -1)
								return str;
							else
								sql = str.substring(i + 5);
						} else
							sql = str.substring(i + 15);
					} else
						sql = str.substring(i + 13);
				} else
					sql = str.substring(i + 8);
			} else
				sql = str.substring(i + 17);

			i = sql.indexOf('Para:');
			if (i == -1) {
				return Helper.htmlEncode(sql);
			}

			var paramStr = sql.substring(i + 5);
			if ($E.logDes) {
				paramStr = decryptByDESModeEBC(paramStr, $E.logDesToken);
			}

			sql = sql.substring(0, i);
			try {
				$F.log('Parameters', paramStr);
				let param = JSON.parse(paramStr);
				//console.log(param);
				$.each(param, function(i, v){
					sql = replaceOneEntry(sql, v)
				})
			} catch (e) {
				// 解密失败的话就不去替换，起到效果就是sql参数不显示在admin上
				// console.error(e, paramStr)
			}

			return Helper.htmlEncode(sql);
		},

		replaceOneEntry = function(sql, entry) {
			var i = sql.indexOf('?');
			if (i == -1)
				return sql;

			var v;
			if (entry.t == 1)
				v = entry.v;
			else
				v = "'" + entry.v + "'";
			return sql.substring(0, i) + v + sql.substring(i+1);
		},

		// DES加密-ECB模式
		encryptByDES = function(message, key) {
			//把私钥转换成16进制的字符串
			var keyHex = CryptoJS.enc.Utf8.parse(key);
			//模式为ECB padding为Pkcs7
			var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
				mode: CryptoJS.mode.ECB,
				padding: CryptoJS.pad.Pkcs7
			});
			//加密出来是一个16进制的字符串
			return encrypted.ciphertext.toString();
		},
		//DES-ECB模式
		decryptByDESModeEBC = function(ciphertext, key) {
			if (! ciphertext)
				return '';

			//把私钥转换成16进制的字符串
			var keyHex = CryptoJS.enc.Utf8.parse(key);
			//把需要解密的数据从16进制字符串转换成字符byte数组
			var decrypted = CryptoJS.DES.decrypt({
				ciphertext: CryptoJS.enc.Hex.parse(ciphertext)
			}, keyHex, {
				mode: CryptoJS.mode.ECB,
				padding: CryptoJS.pad.Pkcs7
			});
			//以utf-8的形式输出解密过后内容
			try {
				return decrypted.toString(CryptoJS.enc.Utf8);
			} catch (e) {
				return ciphertext;
			}
		};

	$(function(){
		window.Logs = Logs;
		require([ 'js/lib/async.min',
			'js/constants.min',
			'js/lib/elasticsearch.client' + $E.jsv], function(async, Constants, elasticsearch) {
			window.$Async = async;
			window.$CONST = Constants;
			window.elasticsearch = elasticsearch;

			elasticsearch.init({
				token : $E.admin.token,
				terminal : 'admin'
			}, function() {
				elasticsearch._status = 'ready';
				$E.initScreen();
				Logs.init();
			}, function() {
				$E.initScreen();
				Logs.init();
				$F.err('VE - init', 'elasticsearch初始化失败');
			});
		});
	});
})(jQuery)
